package com.cb.spzx.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cb.spzx.common.exception.CbException;
import com.cb.spzx.manager.mapper.SysRoleMenuMapper;
import com.cb.spzx.manager.service.SysMenuService;
import com.cb.spzx.manager.mapper.SysMenuMapper;
import com.cb.spzx.manager.utils.MenuHelper;
import com.cb.spzx.model.entity.system.SysMenu;
import com.cb.spzx.model.entity.system.SysRoleMenu;
import com.cb.spzx.model.entity.system.SysUser;
import com.cb.spzx.model.vo.common.ResultCodeEnum;
import com.cb.spzx.model.vo.system.SysMenuVo;
import com.cb.spzx.utils.AuthContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
* @author lenovo
* @description 针对表【sys_menu(菜单表)】的数据库操作Service实现
* @createDate 2024-04-11 11:18:18
*/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService{

    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public List<SysMenu> findNodes() {
        //查询所有菜单
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(SysMenu::getSortValue);
        List<SysMenu> sysMenuList = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(sysMenuList)) {
            return null;
        }
        //构建树形数据
        return MenuHelper.buildTree(sysMenuList);
    }

    @Override
    public int saveMenu(SysMenu sysMenu) {
        // 添加新的节点
        int insert = baseMapper.insert(sysMenu);
        // 新添加一个菜单，那么此时就需要将该菜单所对应的父级菜单设置为半开
        updateSysRoleMenuIsHalf(sysMenu) ;
        return insert;
    }

    private void updateSysRoleMenuIsHalf(SysMenu sysMenu) {
        // 获取当前菜单的父菜单
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getId,sysMenu.getParentId());
        SysMenu sysMenu1 = baseMapper.selectOne(queryWrapper);
        if(sysMenu1!=null){
            // 将该id的菜单设置为半开
            LambdaUpdateWrapper<SysRoleMenu> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(SysRoleMenu::getIsHalf,1).eq(SysRoleMenu::getMenuId,sysMenu1.getParentId());
            sysRoleMenuMapper.update(null,updateWrapper);
            // 递归调用
            updateSysRoleMenuIsHalf(sysMenu1);
        }
    }

    @Override
    public int updateMenu(SysMenu sysMenu) {
        sysMenu.setUpdateTime(new Date());
        return baseMapper.updateById(sysMenu);
    }

    @Override
    public int deleteMenu(Long id) {
        // 先查询是否存在子菜单，如果存在不允许进行删除
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getParentId,id);
        Long count = baseMapper.selectCount(queryWrapper);
        if(count>0){
            throw new CbException(ResultCodeEnum.NODE_ERROR);
        }
        // 不存在子菜单直接删除
        return baseMapper.deleteById(id);
    }

    @Override
    public List<SysMenuVo> findUserMenuList() {
        // 获取当前登录用户的id
        SysUser sysUser = AuthContextUtil.get();
        Long userId = sysUser.getId();
        //根据userId查询可以操作的菜单
        List<SysMenu> sysMenuList=sysMenuMapper.selectListByUserId(userId);
        //封装数据
        List<SysMenu> sysMenuList1 = MenuHelper.buildTree(sysMenuList);
        return buildMenus(sysMenuList1);
    }

    // 将List<SysMenu>对象转换成List<SysMenuVo>对象
    private List<SysMenuVo> buildMenus(List<SysMenu> menus) {
        List<SysMenuVo> sysMenuVoList = new LinkedList<SysMenuVo>();
        for (SysMenu sysMenu : menus) {
            SysMenuVo sysMenuVo = new SysMenuVo();
            sysMenuVo.setTitle(sysMenu.getTitle());
            sysMenuVo.setName(sysMenu.getComponent());
            List<SysMenu> children = sysMenu.getChildren();
            if (!CollectionUtils.isEmpty(children)) {
                sysMenuVo.setChildren(buildMenus(children));
            }
            sysMenuVoList.add(sysMenuVo);
        }
        return sysMenuVoList;
    }
}




